/*
 * #%L
 * java model
 * %%
 * Copyright (C) 2009 - 2011 Stefan Isele
 * %%
 * All Rights Reserved.
 * This program is dual-licensed under the GNU General Public license
 * or a commercial license.
 * You may select to use one or the other of these licenses.
 * To obtain a commercial license please contact Stefan Isele at www.stefan-isele.de
 * Any modifications to this file must keep this entire header intact.
 * Redistribution, except as permitted by the selected license, is prohibited.
 * #L%
 */
package com.prefabware.jmodel.code.equals;

import com.prefabware.jmodel.JType;
import com.prefabware.jmodel.code.JCodeOptions;
import com.prefabware.jmodel.expression.JExpression;
import com.prefabware.jmodel.expression.JVariable;
import com.prefabware.jmodel.expression.JVariableBase;

/**
 * to create implementation of {@link Object#equals(Object)}
 * use {@link #create(JVariableBase)} to create an instance 
 * 
 * @author Stefan Isele
 * 
 */
public class Equals {
	protected abstract class Expression implements JExpression {
		public Expression(String this_, String other) {
			super();
			this.this_ = this_;
			this.other = other;
		}

		String this_;
		String other;
	}

	private JVariable variable;

	/**
	 * 
	 * @param variable
	 * @return a Equals
	 */
	public static Equals create(JVariable variable) {
		JType type = variable.getDeclaration().getType();
		if (type.equalsClass(double.class)) {
			return new Equalsdouble(variable);
		} else if (type.equalsClass(float.class)) {
			return new Equalsfloat(variable);
		} else if (type.isPrimitive()) {
			return new Equalsprimitive(variable);
		} else
			return new Equals(variable);
	};

	/**
	 * for internal use only,
	 * call {@link #create(JVariableBase)} for a new instance
	 * @param variable
	 */
	protected Equals(JVariable variable) {
		super();
		this.variable = variable;
	}

	/**
	 * @param other
	 * @return the expression to compare the {@link #getVariable()} of 'this' to
	 *         the same field of the instance with the given name for
	 *         field.name="field" and other="other" returns :
	 *         "field.equals(other.field)"
	 */
	public JExpression getEquals(String this_, String other) {
		JExpression expression = new Expression(this_, other) {

			@Override
			public String asCode(JCodeOptions options) {
				String field = variable.asCode(JCodeOptions.SIMPLE_NAMES);
				return this_ + "." + field + ".equals(" + other + "." + field
						+ ")";
			}
		};
		return expression;
	}

	public JVariable getVariable() {
		return variable;
	}
}
